﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TVGrid.TVGridService;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.IO;

namespace TVGrid.ViewModel
{
    public class TVGridViewModel:ViewModelBase, IDisposable
    {
        public TVGridViewModel()
        {
            UserLoggedinEvent += new VoidWithNoArgsHendler(TVGridViewModel_UserLoggedinEvent);
            StationAddedEvent += new VoidWithNoArgsHendler(TVGridViewModel_StationAddedEvent);
            UserLoggedoutEvent += new VoidWithNoArgsHendler(TVGridViewModel_UserLoggedoutEvent);
            LoadChannelList();
            if (TvStasions == null)
                TvStasions = new ObservableCollection<Television>();

            UserStations = new ObservableCollection<Television>();

            MyMessenger.Subscribe((Action<LoginMsg>)(OnLogin));
        }


        private void OnLogin(LoginMsg msg)
        {
          
        }

        void TVGridViewModel_UserLoggedoutEvent()
        {
            UserStations = new ObservableCollection<Television>();
        }

        void TVGridViewModel_StationAddedEvent()
        {
            LoadChannelList();
        }

        void TVGridViewModel_UserLoggedinEvent()
        {
            ServiceClient.GetUserStationsCompleted += (s, e) => 
            {
                if (e.Result != null)
                {
                    List<TVStation> result = e.Result.ToList();
                    UserStations = new ObservableCollection<Television>(ConvertTVStationToTelevison(result));
                }
            };
            ServiceClient.GetUserStationsAsync(User.UserID);
        }

        private bool _channelListExpanded;
        public bool ChannelListExpanded
        {
            get { return _channelListExpanded; }
            set
            {
                _channelListExpanded = value;
                OnPropertyChanged("ChannelListExpanded");
            }
        }

        private ObservableCollection<Television> _tvStations;
        public ObservableCollection<Television> TvStasions
        {
            get { return _tvStations; }
            set
            {
                _tvStations = value;
                OnPropertyChanged("TvStasions");
            }
        }

        private ObservableCollection<Television> _userStations;
        public ObservableCollection<Television> UserStations
        {
            get { return _userStations; }
            set
            {
                _userStations = value;
                OnPropertyChanged("UserStations");
            }
        }

        private Television _selectedStationFromList;
        public Television SelectedStationFromList
        {
            get { return _selectedStationFromList; }
            set
            {
                _selectedStationFromList = value;
                OnPropertyChanged("SelectedStationFromList");
            }
        }

        private Television _selectedTvFromList;
        public Television SelectedTVFromList
        {
            get { return _selectedTvFromList; }
            set
            {
                _selectedTvFromList = value;
                OnPropertyChanged("SelectedTVFromList");
            }
        }

        private void LoadChannelList()
        {
            ServiceClient.GetStationsCompleted += (s, e) => 
            {
                List<TVStation> tvs = ServiceClient.GetStations().ToList();
                TvStasions = new ObservableCollection<Television>(ConvertTVStationToTelevison(tvs));
            };
            ServiceClient.GetStationsAsync();
        }

        private void SaveUserSettings()
        {
            if (User.UserID != 0)
            {
                int[] stationsIdArray = new int[UserStations.Count];
                for (int i = 0; i < UserStations.Count; i++)
                {
                    stationsIdArray[i] = UserStations[i].StationID;
                }
                try
                {
                    ServiceClient.SaveUserStationsAsync(User.UserID, stationsIdArray);
                }
                catch
                {
                    throw new Exception("Failed to save settings");
                }
            }
        }

        #region AddUserStationCommand
        RelayCommand _addUserStationCommand;
        public ICommand AddUserStationCommand
        {
            get
            {
                if (_addUserStationCommand == null)
                {
                    _addUserStationCommand = new RelayCommand(p => this.AddUserStation(p),
                    p => this.CanAddUserStation(p));
                }
                return _addUserStationCommand;
            }
        }

        private bool CanAddUserStation(object p)
        {
            return SelectedStationFromList != null;
        }

        private object AddUserStation(object p)
        {
            UserStations.Add(p as Television);
            SaveUserSettings();
            ChannelListExpanded = false;
            return null;
        }
        #endregion

        #region RemovUserStationCommand
        RelayCommand removUserStationCommand;
        public ICommand RemovUserStationCommand
        {
            get
            {
                if (removUserStationCommand == null)
                {
                    removUserStationCommand = new RelayCommand(p => this.RemovUserStation(p),
                    p => this.CanRemovUserStationCommand(p));
                }
                return removUserStationCommand;
            }
        }

        private bool CanRemovUserStationCommand(object p)
        {
            return SelectedTVFromList != null;
        }

        private object RemovUserStation(object p)
        {
            UserStations.Remove(SelectedTVFromList);
            SaveUserSettings();
            return null;
        }
        #endregion

        #region RemoveStationCommand
        RelayCommand _removeStationCommand;
        public ICommand RemoveStationCommand
        {
            get
            {
                if (_removeStationCommand == null)
                {
                    _removeStationCommand = new RelayCommand(p => this.RemoveStation(p),
                    p => this.CanRemoveStationCommand(p));
                }
                return _removeStationCommand;
            }
        }

        private bool CanRemoveStationCommand(object p)
        {
            return true;
        }

        private object RemoveStation(object p)
        {
            try
            {
                ServiceClient.RemoveStationCompleted += (s, e) =>
                {
                    LoadChannelList();
                };
                var tv = p as Television;
                var station = new Station() {Name = tv.StationName, ID = tv.StationID, URL = tv.Address.ToString()};
                ServiceClient.RemoveStationAsync(station);
            }
            catch (Exception ex)
            {
                //ErrorMag = "Failed to remove station";
                //ErrorMagTT = ex.Message;
            }
            return null;
        }
        #endregion

        private List<Television> ConvertTVStationToTelevison(List<TVStation> stations)
        {
            return stations.Select(item => new Television() {Address = item.Address, StationID = item.StationID, StationName = item.StationName, Volume = 0}).ToList();
        }


        public void Dispose()
        {
            MyMessenger.Unsubscribe((Action<LoginMsg>)(OnLogin));
        }
    }
}
